package com.helloandroid

import android.content.Intent
import android.os.Build
import android.os.Looper
import android.util.DisplayMetrics
import android.widget.Toast
import androidx.core.content.edit
import com.anythink.core.api.ATSDK
import com.business.TDKeys
import com.helloandroid.app.model.AppCache
import com.helloandroid.ext.Json
import com.helloandroid.msg.Msg
import com.helloandroid.msg.MsgKey
import com.helloandroid.services.ServerService
import com.helloandroid.tools.AppConfig
import com.helloandroid.tools.GUtils
import com.helloandroid.tools.MyLog
import com.helloandroid.tools.MyTimeUtils
import com.helloandroid.vo.Type
import com.helloandroid.vo.User
import com.hjq.permissions.XXPermissions
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.UMConfigure
import dai.android.util.AndroidUtils
import dai.common.util.CommonUtils
import kotlinx.coroutines.*
import java.util.*
import kotlin.coroutines.EmptyCoroutineContext

object AppUtil {

    val user: User = User(
            user_id = -1,
            coin = 0,
            money = 0,
            tx_count = 0,
            tx_time_stamp = 0L,
            bs = 0,
            bs_sys = 0,
            bs_target = 0,
            signed_count = 0,
            sign_time_stamp = 0L,
            wx_id = "",
            wx_name = "",
            wx_sex = 0,
            wx_icon = ""
    )

    lateinit var app:MyApplication
    lateinit var dm: DisplayMetrics

    // 微信 api
    lateinit var wxApi: IWXAPI
//    private var timer: Timer? = null
    var bsCompletionTimeMs = -1L // 上一次完成今日步数的上报时间

    @JvmStatic
    var sysTime: Long = 0  //

    @JvmStatic
    var isLogin = false

    // 表示是否则在同步玩家信息中
    var syncInfo = SyncInfo()

    // 服务端在线配置
    var serverConfig = ServerConfig()

    fun onLoginSuccess(pUser: User) {
        MyLog.elog("onLoginSuccess called!")
        user.copyFrom(pUser)
        AppCache.init()
        saveIds()

        // 调皮一下, 发个消息给server
        app.serverProxy?.sendMsgToServer(Msg.C2S_LoginOrOut,
                Json {
                    MsgKey.UserId to user.user_id
                    MsgKey.ServerTimeMs to user.loginTime
                    MsgKey.SysBuShu to user.bs_sys
                    MsgKey.BsTarget to user.bs_target
                    MsgKey.CurBs to user.bs
                }.toString()
        )
        // 为了时间里面 tick更快
        syncInfo.updateLoginTime(user.loginTime)
        sysTime = user.loginTime
        isLogin = true

        startBgService()
    }

    fun onLoginFail(pUser: User) {
        val oldUserId = user.user_id
        val oldWxId = user.wx_id
        user.copyFrom(pUser)
        user.user_id = oldUserId
        user.wx_id = oldWxId
        isLogin = false
    }

    fun getWelComeName(): String {
        return if (user.wx_name.isNullOrEmpty()) {
            "游客${CommonUtils.hashNum(user.user_id)}"
        } else {
            user.wx_name
        }
    }

    private fun saveIds() {
        val perf = MyApplication.getPerference(AppConfig.Pref_User)
        perf.edit(commit = true) {
            putInt(AppConfig.KeyUserId, user.user_id)
            putString(AppConfig.KeyWxId, user.wx_id)
        }
    }

    fun reqSyncUser() {

        if (!syncInfo.needSync || syncInfo.syncing) {
            return
        }

        syncInfo.syncing = true

        // 需要重新登陆下
        MyLog.info("reqSyncUser===进行同步数据...... Time:${Date()}")

        // 重新登陆,主要是同步 user 数据
        // 这里不应该打  toast
        appViewModel().syncUser(user.bs_sys) { success ->
            MyLog.info("syncUseruser数据 结果为 ${success},时间=${Date()}")
            syncInfo.syncing = false
        }
    }

    fun checkSyncInfoState(time: Long) {

        // 正在同步 或者需要同步
        if (syncInfo.syncing || syncInfo.needSync) {
            return
        }

        if (time >= syncInfo.syncTime) {
            syncInfo.needSync = true
        }
    }

    @JvmStatic
    fun toast(str: String) {
        if (Looper.getMainLooper().thread.id == Thread.currentThread().id) {
            Toast.makeText(app, str, Toast.LENGTH_SHORT).show()
        } else {
            app.myHandler.post {
                Toast.makeText(app, str, Toast.LENGTH_SHORT).show()
            }
        }
    }

    // 增加金币
    @JvmStatic
    fun increaseCoin(count: Int) {
        user.coin += count
    }

    fun setCoin(total: Int) {
        user.coin = total
    }

    fun setMoney(total:Int){
        user.money = total
    }

    fun updateSignInfo(timeMs: Long, count: Int) {
       user.sign_time_stamp = timeMs
        user.signed_count = count
    }

    // 增加 money
    @JvmStatic
    fun increaseMoney(count: Int) {
       user.money += count
    }

    fun canSign(): Boolean {
        val lastStamp = MyTimeUtils.dayTimeString(user.sign_time_stamp)
        val curStamp = MyTimeUtils.dayTimeString(sysTime)
        MyLog.elog("canSign called!  lastStamp:$lastStamp,curStamp:$curStamp")
        return lastStamp != curStamp
    }

    fun updateUserBs(sysBs: Int): Int {
        if (sysBs > user.bs_sys) {
            user.bs += (sysBs - user.bs_sys)
            user.bs_sys = sysBs
        }
        return user.bs
    }

    @JvmStatic
    fun getCoin(): Int = user.coin

    fun isHbyCanPlay(): Boolean {
        if (AppCache.hbyInfo == null) {
            return false
        }
        val lastHybTimeMs = AppCache.hbyInfo!!.lastTimeMs
        return lastHybTimeMs >= 0 && sysTime - lastHybTimeMs >= GUtils.TenMinutes
    }

    // 红包雨今天的次数完了
    fun isHbyTodayCompleted(): Boolean {
        if (AppCache.hbyInfo == null) {
            return false
        }
        return AppCache.hbyInfo!!.count >= serverConfig.hbyMax1Day
    }

    @JvmStatic
    fun appViewModel() = app.getUserViewModel()

    fun initLocal(pApp:MyApplication){
        app = pApp
        dm = app.resources.displayMetrics
        initWX()
        initUmeng()
        initTopOn()

        val perf = MyApplication.getPerference(AppConfig.Pref_User)
        user.user_id = perf.getInt(AppConfig.KeyUserId, -1)
        user.wx_id = perf.getString(AppConfig.KeyWxId, "").toString()
        MyLog.elog("user_id:${user.user_id}, and wx_id = ${user.wx_id}")

        // 设置权限拦截器
        XXPermissions.setPermissionInterceptor(PermissionInterceptor())
        bsCompletionTimeMs = MyApplication.getPerference(AppConfig.Pref_Local).getLong(AppConfig.KeyBsCompletionReport, 0L)

        startEventLoop()
    }

    // 运行在非 主进程
    fun initOthers(pApp: MyApplication){
        app = pApp
        dm = app.resources.displayMetrics

        //
        // app.registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks)

    }

    private fun initWX() {
        wxApi = WXAPIFactory.createWXAPI(app, TDKeys.WX_APP_ID, false)
        wxApi.registerApp(TDKeys.WX_APP_ID)
    }

    private fun initUmeng() {
        /**
         * 注意: 即使您已经在AndroidManifest.xml中配置过appkey和channel值，也需要在App代码中调
         * 用初始化接口（如需要使用AndroidManifest.xml中配置好的appkey和channel值，
         * UMConfigure.init调用中appkey和channel参数请置为null）。
         */
        UMConfigure.init(app, TDKeys.UMengAppKey, TDKeys.UMengChannel, UMConfigure.DEVICE_TYPE_PHONE, null)
        UMConfigure.setLogEnabled(AppConfig.isDebug)
        UMConfigure.setProcessEvent(true)

        // 选用AUTO页面采集模式
        MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO);

        MyLog.info("channel_name:${TDKeys.UMengChannel}")
    }
    private fun initTopOn() {
        ATSDK.setNetworkLogDebug(AppConfig.isDebug);//SDK日志功能，集成测试阶段建议开启，上线前必须关闭
        ATSDK.init(app, TDKeys.TopOnAppID, TDKeys.TopOnAppKey);//初始化SDK
    }
    private fun startEventLoop(){
        // 开启一个事件循环
        CoroutineScope(EmptyCoroutineContext).launch {
            launch(Dispatchers.Default){
                while (isActive){
                    delay(1000L)
                    withContext(Dispatchers.Main){
                        if (isLogin){
                            sysTime += 1000

                            // 判断是否到了syncUser的时候
                            checkSyncInfoState(sysTime)
                        }
                    }
                }
            }
        }
    }

    // 检查今日步数是否已经完成
    fun checkBsCompletion() {
        if (user.bs >= user.bs_target) {
            // 已经完成,判断今天是否上报过
            // 一天只需要上报一次
            val todayTimeString = MyTimeUtils.dayTimeString(sysTime)
            val lastTimeString = MyTimeUtils.dayTimeString(bsCompletionTimeMs)
            if (todayTimeString != lastTimeString) {
                appViewModel().zhuanReportTask(Type.BuShu)
                bsCompletionTimeMs = sysTime
                MyApplication.getPerference(AppConfig.Pref_Local).edit(commit = true) {
                    putLong(AppConfig.KeyBsCompletionReport, bsCompletionTimeMs)
                }
            }
        }
    }
    fun startBgService() {

        MyLog.info("startBgService called!")

        if (!AndroidUtils.isNotificationEnabled(app)) {
            return
        }

        // 玩家开启了通知
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // 启动前台服务
            if (isLogin) {
                val flag = app.serverProxy!!.queryPrefFlag(Msg.C2S_Pref_Resident)
                // 玩家开启了 打开常驻通知
                if (flag) {
                    val serviceIntent = Intent(app, ServerService::class.java)
                    serviceIntent.putExtra(Msg.IntentKey_IsFake,AppConfig.isFake)

                    // fake的时候 当正常service启动
                    if (AppConfig.isFake){
                        serviceIntent.putExtra(Msg.IntentKey_FgService, Msg.NormalNotification)
                        app.startService(serviceIntent)
                    }else{
                        serviceIntent.putExtra(Msg.IntentKey_FgService, Msg.FgServiceNotification)
                        app.startForegroundService(serviceIntent)
                    }
                }
            }
        } else {
            // 发送正常的通知
            if (isLogin) {
                val flag = app.serverProxy!!.queryPrefFlag(Msg.C2S_Pref_Resident)
                // 玩家开启了 打开常驻通知
                if (flag) {
                    val serviceIntent = Intent(app, ServerService::class.java)
                    serviceIntent.putExtra(Msg.IntentKey_IsFake,AppConfig.isFake)
                    serviceIntent.putExtra(Msg.IntentKey_FgService, Msg.NormalNotification)
                    app.startService(serviceIntent)
                }
            }
        }
    }
}